﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AlertSystem.Business;
using StorageManagement;
using Utils;
using PluggableModulesInterface;
using System.Configuration;

namespace AlertSystem.PluggableModules
{
    public abstract class WorkingBaseSendAlert : WorkingBaseTask, IPluggableModule
    {
        #region 
        public int Key { get; protected set; }
        public string Name { get; protected set; }
        public string Type { get; protected set; }
        public bool Running
        {
            get
            {
                return (taskList.Count > 0);
            }
        }
        public string AssemblyLocation { private get; set; }
        public int BatchSize { get { return GetConfig("BatchSize").ToInt(); } set { SetConfig("BatchSize", value.ToString()); } }
        protected Warning_Method Method
        {
            get
            {
                return Warning_Method.GetByObjectType(ObjectType);
            }
        }
        #endregion propeties

        #region constructor
        public WorkingBaseSendAlert()
            : base()
        {
            if (this.Method != null)
            {
                this.Key = Method.Method_Id;
                this.Name = Method.Method_Name;
                this.Type = Method.Method_Type;
            }
        }
        #endregion constructor

        #region Loop
        public override void Start()
        {
            base.Start();
            Warning_Method method = Warning_Method.GetByID(this.Key);
            if (method != null)
            {
                method.Started = IsStart;
                method.Save();
            }
        }

        public override void Stop()
        {
            if (IsStart)
            {
                Business.Warning_Log.InsertLog(string.Format("Waring method has Stopped, Key: {0}, Method Name: {1}, Method Type: {2}, Ojbect Type: {3}", this.Key, this.Name, this.Type, this.ObjectType), "WorkingBaseTask.Stop", this.ObjectType);
            }
            base.Stop();
            Warning_Method method = Warning_Method.GetByID(this.Key);
            if (method != null)
            {
                method.Started = IsStart;
                method.Save();
            }
        }

        protected override void LoopWorking()
        {
            List<Warning_Message> msgList = DictionaryStorage<int, Warning_Message>.DequeueElementData(this.Key, BatchSize);
            if (msgList != null && msgList.Count > 0)
            {
                foreach (var msg in msgList)
                {                    
                    List<Warning_Account_Method> listAccMethod = Warning_Account_Method.FindItems(wam => wam.Method_Id == this.Key
                                && Warning_System_Type_Account.Any(wsya => wsya.Account_Id == wam.Account_Id
                                            && wsya.System_Id == msg.WarningSystem
                                            && wsya.WarningType == msg.WarningType)
                                ).ToList();
                    Send(msg, listAccMethod);
                }
            }
        }

        protected abstract void Send(Warning_Message msgList, List<Warning_Account_Method> accountMethods);

        #endregion Loop

        #region method
        public string GetAssemblyLocation()
        {
            return AssemblyLocation;
        }

        protected string GetConfig(string configKey)
        {
            return ConfigurationManager.OpenExeConfiguration(this.AssemblyLocation)
                    .AppSettings.Settings[configKey].Value;
        }

        protected void SetConfig(string configKey, string value)
        {
            Configuration configuration = ConfigurationManager.OpenExeConfiguration(this.AssemblyLocation);
            if (configuration.AppSettings.Settings[configKey] == null)
                configuration.AppSettings.Settings.Add(new KeyValueConfigurationElement(configKey, value));
            else
                configuration.AppSettings.Settings[configKey].Value = value;
            configuration.Save();
        }


        public void CollectGarbage()
        {
            GC.Collect();
        }
        #endregion method
    }
}
